package com.bright.cwduijie.duijie.manager.impl;

import com.bright.cwduijie.common.util.StringUtil;
import com.bright.cwduijie.duijie.constant.ConfigConstants;
import com.bright.cwduijie.duijie.converter.*;
import com.bright.cwduijie.duijie.enums.OpType;
import com.bright.cwduijie.duijie.enums.SJJHBZ;
import com.bright.cwduijie.duijie.manager.DataManager;
import com.bright.cwduijie.duijie.pojo.command.MonthlySettledCommand;
import com.bright.cwduijie.duijie.pojo.command.BuildCommand;
import com.bright.cwduijie.duijie.pojo.dto.*;
import com.bright.cwduijie.duijie.pojo.po.*;
import com.bright.cwduijie.duijie.pojo.query.DuijieQuery;
import com.bright.cwduijie.duijie.repository.*;
import com.bright.cwduijie.duijie.util.EntityManagerUtil;
import com.bright.cwduijie.duijie.util.ListUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author hxj
 * @Date 2024/7/4 16:13
 * @Description
 */

@Component
@RequiredArgsConstructor
@Slf4j
public class DataManagerImpl implements DataManager {

    private final AccSetRepository accSetRepository;
    private final AccCodeRepository accCodeRepository;

//    private final BalanceRepository balanceRepository;
//    private final CreditPublishRepository creditPublishRepository;
//    private final DebtPublishRepository debtPublishRepository;
//    private final FixedAssetsDepreciationLogRepository fixedAssetsDepreciationLogRepository;
//    private final FixedAssetsHandleLogRepository fixedAssetsHandleLogRepository;
//    private final FixedAssetsInfoChangeRepository fixedAssetsInfoChangeRepository;
//    private final FixedAssetsValueChangeRepository fixedAssetsValueChangeRepository;
//    private final MonthlySettlementRepository monthlySettlementRepository;
    private final VoucherRepository voucherRepository;
    private final VoucherEntryRepository voucherEntryRepository;
//    private final FixedAssetsRepository fixedAssetsRepository;
//    private final DayBooksRepository dayBooksRepository;
//    private final ContractRepository contractRepository;
    private final AccSetConverter accSetConverter;
    private final AccCodeConverter accCodeConverter;
//    private final BalanceConverter balanceConverter;
//    private final CreditPublishConverter creditPublishConverter;
//    private final DebtPublishConverter debtPublishConverter;
//    private final FixedAssetsDepreciationLogConverter fixedAssetsDepreciationLogConverter;
//    private final FixedAssetsHandleLogConverter fixedAssetsHandleLogConverter;
//    private final FixedAssetsInfoChangeConverter fixedAssetsInfoChangeConverter;
//    private final FixedAssetsValueChangeConverter fixedAssetsValueChangeConverter;
//    private final MonthlySettlementConverter monthlySettlementConverter;
    private final VoucherConverter voucherConverter;
    private final VoucherEntryConverter voucherEntryConverter;
    private final EntityManager entityManager;

    private final ConfigConstants constants;

    private final DjFileRepository djFileRepository;


//    @Override
//    public List<AccSetDto> getNeedDuijieAccSets() {
//        List<AccSet> accSets = accSetRepository.getAccSetBySjjhbz(SJJHBZ.WAITING.getValue());
//        return accSetConverter.poConvertDTO(accSets);
//    }
//
//    @Override
//    @Deprecated
//    public Map<AccSetDto, List<AccCodeDto>> getNeedDuijieAccCodeMap() {
//        Map<AccSetDto, List<AccCodeDto>> result = new HashMap<>();
//
//        // 先看有哪些账套
////        List<String> ztDataKeys = accCodeRepository.getDistinctZtDataKeyBySjjhbz(SJJHBZ.WAITING.getValue());
////        for (String ztDataKey : ztDataKeys) {
////            AccSet accSet = accSetRepository.getAccSetByDATAKEY(ztDataKey);
////            AccSetDto accSetDto = accSetConverter.poConvertDTO(accSet);
////            List<AccCode> accCodes = accCodeRepository.getAccCodesByZTDATAKEYAndYears(ztDataKey, SJJHBZ.WAITING.getValue());
////            List<AccCodeDto> accCodeDtos = accCodeConverter.poConvertDTO(accCodes);
////
////            result.put(accSetDto, accCodeDtos);
////        }
//
//
//        return result;
//    }
//
//    @Override
//    public List<FixedAssetsDepreciationLog> getNeedDuijieFixedAssetsDepreciationLogs(DuijieQuery duijieQuery) {
//        List<FixedAssetsDepreciationLog> fixedAssetsDepreciationLogs =
//                fixedAssetsDepreciationLogRepository.getBySjjhbzAndZtDataKey(SJJHBZ.WAITING.getValue(), duijieQuery.getZtDataKey());
//        fixedAssetsDepreciationLogs.addAll(fixedAssetsDepreciationLogRepository.getBySjjhbzAndZtDataKey(SJJHBZ.ERROR.getValue(), duijieQuery.getZtDataKey()));
////        return fixedAssetsDepreciationLogConverter.poConvertDTO(fixedAssetsDepreciationLogs);
//        return fixedAssetsDepreciationLogs;
//    }
//
//    @Override
//    public List<FixedAssetsHandleLog> getNeedDuijieFixedAssetsHandleLogs(DuijieQuery duijieQuery) {
//        List<FixedAssetsHandleLog> fixedAssetsHandleLogs =
//                fixedAssetsHandleLogRepository.getBySjjhbzAndZtDataKey(SJJHBZ.WAITING.getValue(), duijieQuery.getZtDataKey());
//        fixedAssetsHandleLogs.addAll(fixedAssetsHandleLogRepository.getBySjjhbzAndZtDataKey(SJJHBZ.ERROR.getValue(), duijieQuery.getZtDataKey()));
////        return fixedAssetsHandleLogConverter.poConvertDTO(fixedAssetsHandleLogs);
//        return fixedAssetsHandleLogs;
//    }
//
//    @Override
//    public List<FixedAssetsInfoChange> getNeedDuijieFixedAssetsInfoChanges(DuijieQuery duijieQuery) {
//        List<FixedAssetsInfoChange> fixedAssetsInfoChanges =
//                fixedAssetsInfoChangeRepository.getBySjjhbzAndZtDataKey(SJJHBZ.WAITING.getValue(), duijieQuery.getZtDataKey());
//        fixedAssetsInfoChanges.addAll(fixedAssetsInfoChangeRepository.getBySjjhbzAndZtDataKey(SJJHBZ.ERROR.getValue(), duijieQuery.getZtDataKey()));
////        return fixedAssetsInfoChangeConverter.poConvertDTO(fixedAssetsInfoChanges);
//        return fixedAssetsInfoChanges;
//    }
//
//    @Override
//    public List<FixedAssetsValueChange> getNeedDuijieFixedAssetsValueChange(DuijieQuery duijieQuery) {
//        List<FixedAssetsValueChange> fixedAssetsValueChanges =
//                fixedAssetsValueChangeRepository.getBySjjhbzAndZtDataKey(SJJHBZ.WAITING.getValue(), duijieQuery.getZtDataKey());
//        fixedAssetsValueChanges.addAll(fixedAssetsValueChangeRepository.getBySjjhbzAndZtDataKey(SJJHBZ.ERROR.getValue(), duijieQuery.getZtDataKey()));
////        return fixedAssetsValueChangeConverter.poConvertDTO(fixedAssetsValueChanges);
//        return fixedAssetsValueChanges;
//    }
//
//    @Override
//    public List<ApiNeedDuijieDto> getNeedDuijieAccSetsOfAllApi() {
//        List<ApiNeedDuijieDto> result = new ArrayList<>();
//
//        // key=ztDataKey  value=apis
//        // 记录所有需要对接的账套
//        Set<String> dataKeySet = new HashSet<>();
//
//        // 这里只用看所有根据账套表走的
//        // 账套表
//        int sjjhbzWaiting = SJJHBZ.WAITING.getValue();
//        int sjjhbzError = SJJHBZ.ERROR.getValue();
//        List<AccSet> accSetBySjjhbz = accSetRepository.getAccSetBySjjhbz(sjjhbzWaiting);
//        accSetBySjjhbz.addAll(accSetRepository.getAccSetBySjjhbz(sjjhbzError));
//        List<String> accSetDataKeys = ListUtil.toSingleList(accSetBySjjhbz, AccSet::getDATA_KEY);
//        dataKeySet.addAll(accSetDataKeys);
//
//        // 账套科目初始化数据
//        List<String> accCodeDataKeys = accCodeRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzWaiting);
//        accCodeDataKeys.addAll(accCodeRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzError));
//        dataKeySet.addAll(accCodeDataKeys);
//
//        // 凭证
//        List<String> voucherDataKeys = voucherRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzWaiting);
//        voucherDataKeys.addAll(voucherRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzError));
//        dataKeySet.addAll(voucherDataKeys);
//
//        // 资产负债表
//        List<String> balanceDataKeys = balanceRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzWaiting);
//        balanceDataKeys.addAll(balanceRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzError));
//        dataKeySet.addAll(balanceDataKeys);
//
//        // 债务公布表
//        List<String> creditPublishDataKeys = creditPublishRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzWaiting);
//        creditPublishDataKeys.addAll(creditPublishRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzError));
//        dataKeySet.addAll(creditPublishDataKeys);
//
//        // 债权公布表
//        List<String> debtPublishDataKeys = debtPublishRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzWaiting);
//        debtPublishDataKeys.addAll(debtPublishRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzError));
//        dataKeySet.addAll(debtPublishDataKeys);
//
//        // 月结表
//        List<String> monthlySettlementDataKeys = monthlySettlementRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzWaiting);
//        monthlySettlementDataKeys.addAll(monthlySettlementRepository.getDistinctZtDataKeyBySjjhbz(sjjhbzError));
//        dataKeySet.addAll(monthlySettlementDataKeys);
//
//        //  固定资产主表（还有4个记录？）
//        Set<String> tyshxydmSet = new HashSet<>();
//        List<String> fixedAssetsTYSHXYDMs = fixedAssetsRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzWaiting);
//        fixedAssetsTYSHXYDMs.addAll(fixedAssetsRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzError));
//        tyshxydmSet.addAll(fixedAssetsTYSHXYDMs);
//
//        List<String> fixedAssetsDepreciationLogTYSHXYDMs = fixedAssetsDepreciationLogRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzWaiting);
//        fixedAssetsDepreciationLogTYSHXYDMs.addAll(fixedAssetsDepreciationLogRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzError));
//        tyshxydmSet.addAll(fixedAssetsDepreciationLogTYSHXYDMs);
//
//        List<String> fixedAssetsHandleLogTYSHXYDMs = fixedAssetsHandleLogRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzWaiting);
//        fixedAssetsHandleLogTYSHXYDMs.addAll(fixedAssetsHandleLogRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzError));
//        tyshxydmSet.addAll(fixedAssetsHandleLogTYSHXYDMs);
//
//        List<String> fixedAssetsInfoChangeTYSHXYDMs = fixedAssetsInfoChangeRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzWaiting);
//        fixedAssetsInfoChangeTYSHXYDMs.addAll(fixedAssetsInfoChangeRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzError));
//        tyshxydmSet.addAll(fixedAssetsInfoChangeTYSHXYDMs);
//
//        List<String> fixedAssetsValueChangeTYSHXYDMs = fixedAssetsValueChangeRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzWaiting);
//        fixedAssetsValueChangeTYSHXYDMs.addAll(fixedAssetsValueChangeRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzError));
//        tyshxydmSet.addAll(fixedAssetsValueChangeTYSHXYDMs);
//
//        // 收支日记账
//        List<String> dayBooksTYSHXYDMs = dayBooksRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzWaiting);
//        dayBooksTYSHXYDMs.addAll(dayBooksRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzError));
//        tyshxydmSet.addAll(dayBooksTYSHXYDMs);
//
//        // 合同信息
//        List<String> contractTYSHXYDMs = contractRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzWaiting);
//        contractTYSHXYDMs.addAll(contractRepository.getDistinctTYSHXYDMBySjjhbz(sjjhbzError));
//        tyshxydmSet.addAll(contractTYSHXYDMs);
//
//        dataKeySet.addAll(getZtDataKeyByCreditCodes(tyshxydmSet));
//
//
//        // 根据所有账套 创建ApiNeedDuijieDto
//        for (String dataKey : dataKeySet) {
//            List<DataApi> apis = new ArrayList<>(16);
//            ApiNeedDuijieDto api = new ApiNeedDuijieDto(dataKey, apis);
//            result.add(api);
//
////            // 判断每个接口是否需要推这个账套
////            if (accSetDataKeys.contains(dataKey)) {
////                apis.add(DataApi.ACC_SET);
////            }
////
////            if (accCodeDataKeys.contains(dataKey)) {
////                apis.add(DataApi.ACC_CODE);
////            }
////
////            if (voucherDataKeys.contains(dataKey)) {
////                apis.add(DataApi.VOUCHER);
////            }
////
////            if (balanceDataKeys.contains(dataKey)) {
////                apis.add(DataApi.BALANCE);
////            }
////
////            if (creditPublishDataKeys.contains(dataKey)) {
////                apis.add(DataApi.CREDIT_PUBLISH);
////            }
////
////            if (debtPublishDataKeys.contains(dataKey)) {
////                apis.add(DataApi.DEBT_PUBLISH);
////            }
////
////            // 固定资产4个记录表 只要上面那些要传 就都一起传 这里只用给一个DataApi即可
////            apis.add(DataApi.FIXED_ASSETS_INFO_CHANGE);
//        }
//        return result;
//    }

    @Override
    public Set<String> getZtDataKeyByCreditCodes(Set<String> tyshxydmSet) {
        Set<String> dataKeySet = new HashSet<>();
        // 根据信用代码获取账套信息 一千次一次
        int count = 0;
        List<String> tyshxydmList = new ArrayList<>(tyshxydmSet);
        while (count < tyshxydmSet.size()) {
            Set<String> subList = ListUtil.getSubSet(tyshxydmList, count, count + 1000);
            List<AccSet> accSetsByTYSHXYDM = accSetRepository.getAccSetsByTYSHXYDM(subList);
            List<String> tyshxydmDataKeys = ListUtil.toSingleList(accSetsByTYSHXYDM, AccSet::getDATA_KEY);
            dataKeySet.addAll(tyshxydmDataKeys);
            count += 1000;
        }
        return dataKeySet;
    }

//    @Override
//    public void saveAccSetResult(List<AccSetDto> accSetDtos) {
//        List<AccSet> accSets = accSetConverter.dtoConvertPO(accSetDtos);
//        accSetRepository.saveAll(accSets);
//    }

    @Override
    @Nullable
    public AccSetDto getAccSet(DuijieQuery duijieQuery) {
        AccSet accSet;
//        if (duijieQuery.getAccSetDataKey() != null) {
        accSet = accSetRepository.getAccSetByDATAKEY(duijieQuery.getZtDataKey());
//        } else {
//            // 如果没传指定哪个data_key 则全部账套数据进行返回
//            accSet = accSetRepository.findAll();
//        }
        return accSetConverter.poConvertDTO(accSet);
    }

    @Override
    public List<AccSet> getAllAccSetsByTYSHXYDM(DuijieQuery duijieQuery) {
        Set<String> creditCodesSet = new HashSet<>();
        if (duijieQuery.getCreditCode() != null) {
            creditCodesSet.add(duijieQuery.getCreditCode());
        } else if (duijieQuery.getCreditCodes() != null) {
            creditCodesSet.addAll(duijieQuery.getCreditCodes());
        }
        List<String> creditCodesList = new ArrayList<>(creditCodesSet);
        List<AccSet> result = new ArrayList<>();
        int count = 0;
        while (count < creditCodesSet.size()) {
            Set<String> subSet = ListUtil.getSubSet(creditCodesList, count, count + 1000);
            List<AccSet> accSetsByTYSHXYDM = accSetRepository.getAccSetsByTYSHXYDM(subSet);
            result.addAll(accSetsByTYSHXYDM);
            count+=1000;
        }
        return result;
    }

    @Override
    public AccSet getAccSetPO(DuijieQuery duijieQuery) {
        return accSetRepository.getAccSetByDATAKEY(duijieQuery.getZtDataKey());
    }

    @Override
    public List<AccSet> getAccSetsByDataKeys(DuijieQuery duijieQuery) {
        List<AccSet> accSetsByDATAKEYS = new ArrayList<>();
        List<String> ztDataKeys = duijieQuery.getZtDataKeys();
        // 进行去重
        ztDataKeys = ztDataKeys.stream().distinct().collect(Collectors.toList());
        int count = 0;
        while (count < ztDataKeys.size()) {
            List<String> subList = ListUtil.getSubList(ztDataKeys, count, count + 1000);
            List<AccSet> accSets;
            if (duijieQuery.getOpType() == null) {
                accSets = accSetRepository.getAccSetsByDATAKEYS(subList);
            } else {
                accSets = accSetRepository.getAccSetsByDATAKEYSAndOpType(subList, duijieQuery.getOpType().getValue());
            }
            accSetsByDATAKEYS.addAll(accSets);
            count += 1000;
        }
        return accSetsByDATAKEYS;
    }

    @Override
    public List<AccCodeDto> getAccCodes(DuijieQuery duijieQuery) {
        Integer years = duijieQuery.getDuijieYears() == null ? Calendar.getInstance().get(Calendar.YEAR) : duijieQuery.getDuijieYears();
        List<AccCode> accCodes = accCodeRepository.getAccCodesByZTDATAKEYAndYearsAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.WAITING.getValue(), OpType.ADD_OR_EDIT.getValue(), years);
        accCodes.addAll(accCodeRepository.getAccCodesByZTDATAKEYAndYearsAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.ERROR.getValue(), OpType.ADD_OR_EDIT.getValue(), years));
        return accCodeConverter.poConvertDTO(accCodes);
    }

//    @Override
//    public Map<String, List<BalanceDto>> getBalances(DuijieQuery duijieQuery) {
//        List<String> yearMonths = balanceRepository.getDistinctSSQJByZtDataKey(duijieQuery.getZtDataKey());
//        Map<String, List<BalanceDto>> result = new HashMap<>();
//
//        // 20240725 加上判断是否有指定对接年月 若有指定就只返回指定年月的数据 没有就返回全部
//        // 比如只指定了2024年 则selectedYearMonth=2024  若指定2024年1月 则=202401
//        String selectedYearMonth = getSelectedYearMonth(duijieQuery);
//
//        for (String yearMonth : yearMonths) {
//            if (selectedYearMonth == null || StringUtil.startsWith(yearMonth, selectedYearMonth)) {
//                // 只推送选定年月的数据
//                List<Balance> balances = balanceRepository.getByZTDATAKEYAndSSQJ(duijieQuery.getZtDataKey(), yearMonth);
////            balances.addAll(balanceRepository.getByZTDATAKEYAndSSQJ(duijieQuery.getAccSetDataKey(), yearMonth, SJJHBZ.ERROR.getValue()));
//                result.put(yearMonth, balanceConverter.poConvertDTO(balances));
//            }
//
//        }
//        return result;
//    }
//
//    // 根据对接年份和月份构造yearMonth 注：允许只传年份和年份月份必传 若没传年份 则月份不起效
//    private String getSelectedYearMonth(DuijieQuery duijieQuery) {
//        String selectedYearMonth = null;
//        if (duijieQuery.getDuijieYears() != null) {
//            selectedYearMonth = "" + duijieQuery.getDuijieYears();
//            if (duijieQuery.getDuijieMonths() != null) {
//                selectedYearMonth += duijieQuery.getDuijieMonths() < 10 ? duijieQuery.getDuijieMonths() : "0" + duijieQuery.getDuijieMonths();
//            }
//        }
//        return selectedYearMonth;
//    }
//
//    @Override
//    public Map<String, List<CreditPublishDto>>  getCreditPublishes(DuijieQuery duijieQuery) {
//        List<String> yearMonths = creditPublishRepository.getDistinctSSQJByZtDataKey(duijieQuery.getZtDataKey());
//        Map<String, List<CreditPublishDto>> result = new HashMap<>();
//
//        // 20240725 加上判断是否有指定对接年月 若有指定就只返回指定年月的数据 没有就返回全部
//        // 比如只指定了2024年 则selectedYearMonth=2024  若指定2024年1月 则=202401
//        String selectedYearMonth = getSelectedYearMonth(duijieQuery);
//
//        for (String yearMonth : yearMonths) {
//            if (selectedYearMonth == null || StringUtil.startsWith(yearMonth, selectedYearMonth)) {
//                // 只推送选定年月的数据
//                List<CreditPublish> creditPublishes = creditPublishRepository.getByZTDATAKEYAndSSQJ(duijieQuery.getZtDataKey(), yearMonth);
//                result.put(yearMonth, creditPublishConverter.poConvertDTO(creditPublishes));
//            }
//        }
//        return result;
//    }
//
//    @Override
//    public Map<String, List<DebtPublishDto>> getDebtPublishes(DuijieQuery duijieQuery) {
//        List<String> yearMonths = debtPublishRepository.getDistinctSSQJByZtDataKey(duijieQuery.getZtDataKey());
//        Map<String, List<DebtPublishDto>> result = new HashMap<>();
//
//        // 20240725 加上判断是否有指定对接年月 若有指定就只返回指定年月的数据 没有就返回全部
//        // 比如只指定了2024年 则selectedYearMonth=2024  若指定2024年1月 则=202401
//        String selectedYearMonth = getSelectedYearMonth(duijieQuery);
//
//        for (String yearMonth : yearMonths) {
//            if (selectedYearMonth == null || StringUtil.startsWith(yearMonth, selectedYearMonth)) {
//                // 只推送选定年月的数据
//                List<DebtPublish> debtPublishes = debtPublishRepository.getByZTDATAKEYAndSSQJ(duijieQuery.getZtDataKey(), yearMonth);
//                result.put(yearMonth, debtPublishConverter.poConvertDTO(debtPublishes));
//            }
//        }
//        return result;
//    }
//
//    @Override
//    public List<MonthlySettlementDto> getMonthlySettlement(DuijieQuery duijieQuery) {
//        List<MonthlySettlement> monthlySettlements = monthlySettlementRepository.getByZTDATAKEYAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.WAITING.getValue());
////        String yearMonth = "" + duijieQuery.getDuijieYears() +
////                (duijieQuery.getDuijieMonths() < 10 ? ("0" + duijieQuery.getDuijieMonths()) : duijieQuery.getDuijieMonths());
//
//        // 20240725 对接年月变成可以不指定了 为空时要处理 也要考虑只传年份不传月份的情况
//        String selectedYearMonth = getSelectedYearMonth(duijieQuery);
//
////        List<MonthlySettlement> monthlySettlements = monthlySettlementRepository.getByZTDATAKEYAndYearMonth(duijieQuery.getZtDataKey(), yearMonth);
//        // 20240722 根据sjjhbz=0或2去获取要推的月结数据
//        if (selectedYearMonth == null) {
//            monthlySettlements.addAll(monthlySettlementRepository.getByZTDATAKEYAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.ERROR.getValue()));
//        }
//
//        // 再根据账套和年月获取当前推送的年月是否要月结的数据 不管sjjhbz
//        Set<MonthlySettlement> monthlySettlementsSet = new HashSet<>(monthlySettlements);
//        monthlySettlementsSet.addAll(monthlySettlementRepository.getByZTDATAKEYAndYearMonth(duijieQuery.getZtDataKey(), selectedYearMonth));
//        return monthlySettlementConverter.poConvertDTO(new ArrayList<>(monthlySettlementsSet));
//    }
//
//    @Override
//    public List<MonthlySettlementDto> getMonthlySettlementByYearMonth(DuijieQuery duijieQuery, String yearMonth) {
//        List<MonthlySettlement> monthlySettlements = monthlySettlementRepository.getByYearMonthAndSjjhbz(yearMonth, SJJHBZ.SUCCESS.getValue());
//        return monthlySettlementConverter.poConvertDTO(monthlySettlements);
//    }

    @Override
    public List<VoucherDto> getVouchers(DuijieQuery duijieQuery) {
        // TODO 改成查询最近6个月需要对接的数据
        List<Voucher> vouchers = voucherRepository.getByZTDATAKEYAndOpTypeAndSJJHBZ(duijieQuery.getZtDataKey(), duijieQuery.getOpType().getValue(), SJJHBZ.WAITING.getValue());
        vouchers.addAll(voucherRepository.getByZTDATAKEYAndOpTypeAndSJJHBZ(duijieQuery.getZtDataKey(), duijieQuery.getOpType().getValue(), SJJHBZ.ERROR.getValue()));
        return voucherConverter.poConvertDTO(vouchers);
    }

    @Override
    public List<VoucherEntryDto> getVoucherEntries(DuijieQuery duijieQuery) {
        List<VoucherEntry> voucherEntries = voucherEntryRepository.getAllByDataKey(duijieQuery.getZtDataKey());

        List<VoucherEntryDto> voucherEntryDtos = voucherEntryConverter.poConvertDTO(voucherEntries);
        processVoucherEntries(voucherEntryDtos);

        return voucherEntryDtos;
    }

//    @Override
//    public Map<String, List<VoucherEntryDto>> getVoucherEntriesByZtDataKey(DuijieQuery duijieQuery) {
//        // 这个不同的地方是按账套号全部获取的
//        List<VoucherEntry> voucherEntries = voucherEntryRepository.getAllByZtDataKey(duijieQuery.getZtDataKey());
//
//        List<VoucherEntryDto> voucherEntryDtos = voucherEntryConverter.poConvertDTO(voucherEntries);
//        processVoucherEntries(voucherEntryDtos);
//
//        Map<String, List<VoucherEntryDto>> result = new HashMap<>();
//        // 按data_key分组
//        for (VoucherEntryDto voucherEntryDto : voucherEntryDtos) {
//            String dataKey = voucherEntryDto.getDATA_KEY();
//            if (!result.containsKey(dataKey)) {
//                result.put(dataKey, new ArrayList<>());
//            }
//            result.get(dataKey).add(voucherEntryDto);
//        }
//
//        return result;
//    }

    private void processVoucherEntries(List<VoucherEntryDto> voucherEntryDtos) {
        // 第三方要求借方或贷方没有数值的 不能传0 应该传null
        for (VoucherEntryDto voucherEntry : voucherEntryDtos) {
            String jf_je = voucherEntry.getJF_JE();
            String df_je = voucherEntry.getDF_JE();
            if (StringUtil.equals(jf_je, "0.00") || StringUtil.equals(jf_je, "0.0") || StringUtil.equals(jf_je, "0")) {
                voucherEntry.setJF_JE("");
            }
            if (StringUtil.equals(df_je, "0.00") || StringUtil.equals(df_je, "0.0") || StringUtil.equals(df_je, "0")) {
                voucherEntry.setDF_JE("");
            }

            // 去空格
            voucherEntry.setKJKM_BM(StringUtil.trim(voucherEntry.getKJKM_BM()));
        }
    }

//    @Override
//    public List<FixedAssets> getFixedAssets(DuijieQuery duijieQuery) {
//        List<FixedAssets> fixedAssets = fixedAssetsRepository.getAllByZtDataKeyAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.WAITING.getValue(), duijieQuery.getOpType().getValue());
//        fixedAssets.addAll(fixedAssetsRepository.getAllByZtDataKeyAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.ERROR.getValue(), duijieQuery.getOpType().getValue()));
//        return fixedAssets;
//    }
//
//    @Override
//    public List<DayBooks> getDayBooks(DuijieQuery duijieQuery) {
//        List<DayBooks> dayBooks = dayBooksRepository.getAllByZtDataKeyAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.WAITING.getValue(), duijieQuery.getOpType().getValue());
//        dayBooks.addAll(dayBooksRepository.getAllByZtDataKeyAndSjjhbz(duijieQuery.getZtDataKey(), SJJHBZ.ERROR.getValue(), duijieQuery.getOpType().getValue()));
//        return dayBooks;
//    }
//
//    @Override
//    public List<Contract> getContracts(DuijieQuery duijieQuery) {
//        List<Contract> contracts = contractRepository.getAllByTYSHXYDMAndSjjhbzAndOpType(duijieQuery.getCreditCode(), SJJHBZ.WAITING.getValue(), duijieQuery.getOpType().getValue());
//        contracts.addAll(contractRepository.getAllByTYSHXYDMAndSjjhbzAndOpType(duijieQuery.getCreditCode(), SJJHBZ.ERROR.getValue(), duijieQuery.getOpType().getValue()));
//        return contracts;
//    }

    @Override
    @Transactional
    public void executeMonthlySettled(MonthlySettledCommand command) {
        Map<String, Object> params = new HashMap<>();
        params.put("zucode", command.getZtCreditCode());
        List<Map<String, Object>> maps = EntityManagerUtil.queryForMapList(entityManager,
                "select acc_set as ACC_SET from " + getCwDBName() + "acc_set where zucode=:zucode", params);
        if (maps.size() > 0) {
            Object acc_set = maps.get(0).get("ACC_SET");
            String updateSQL = "exec " + getCwDBName() + "DZ_ZTYJ " + acc_set + ", " + command.getYears() + ", " + command.getMonths() + ", null";
            EntityManagerUtil.update(entityManager, updateSQL, new HashMap<>());
        } else {
            log.info("财务库acc_set表查询统一认证信用代码失败！影响月结！" + command.getZtCreditCode());
        }
    }

    @Override
    public String getCwDBName() {
        String cwdb = constants.getCwdb();
        if (StringUtil.isNotEmpty(cwdb)) {
            return cwdb + "..";
        }
        // 如果财务库名称未配置 则从中间库直接取
        return "";
    }

    @Override
    public String getZcDBName() {
        String zcdb = constants.getZcdb();
        if (StringUtil.isNotEmpty(zcdb)) {
            return zcdb + "..";
        }
        // 如果资产库名称未配置 则从中间库直接取
        return "";
    }

    @Override
    public String getDistNameByDistNo(String distNo) {
        List<Map<String, Object>> list = EntityManagerUtil.queryForMapList(entityManager, "select top 1 distName as distName from " + getZcDBName() + "dist where distNo=:distNo",
                Collections.singletonMap("distNo", distNo));
        if (list.size() == 0) return null;
        return (String) list.get(0).get("distName");
    }

    @Override
    @Transactional
    public void executeSPT(Object accSet, BuildCommand buildCommand) {
        String updateSql = "exec " + getCwDBName() + "DZ_SPT " + accSet + ", " + buildCommand.getYears() + ", " + buildCommand.getMonths() + ", null;";
        EntityManagerUtil.update(entityManager, updateSql, new HashMap<>());
    }

    @Override
    public List<String> getZtDataKeyByAccSets(List<Object> accSets) {
        Map<String, Object> params = new HashMap<>();

        int count = 0;
        List<String> allCreditCodes = new ArrayList<>();
        while (count < accSets.size()) {
            List<Object> subList = ListUtil.getSubList(accSets, count, count + 1000);

            params.put("acc_set", subList);
            List<Map<String, Object>> maps = EntityManagerUtil.queryForMapList(entityManager,
                    "select zucode as ZUCODE from " + getCwDBName() + "acc_set where acc_set in (:acc_set)", params);
            List<String> creditCodes = ListUtil.toSingleList(maps, map -> (String) map.get("ZUCODE"));
            allCreditCodes.addAll(creditCodes);
            count+= 1000;
        }
        DuijieQuery duijieQuery = new DuijieQuery();
        duijieQuery.setCreditCodes(allCreditCodes);
        List<AccSet> allAccSetsByTYSHXYDM = getAllAccSetsByTYSHXYDM(duijieQuery);
        return ListUtil.toSingleList(allAccSetsByTYSHXYDM, AccSet::getDATA_KEY);
    }


//    public String getZtDataKeyByAccSet(Object accSet) {
//        return null;
//    }


    @Override
    public List<DjFile> getNeedDuiJieFiles(DuijieQuery duijieQuery) {
        List<DjFile> allFiles = djFileRepository.getAllFiles(SJJHBZ.WAITING.getValue(), duijieQuery.getOpType().getValue(), duijieQuery.getCreditCode());
        allFiles.addAll(djFileRepository.getAllFiles(SJJHBZ.ERROR.getValue(), duijieQuery.getOpType().getValue(), duijieQuery.getCreditCode()));
        return allFiles;
    }

    @Override
    public List<Map<String, Object>> getDistsByDistNoAndLevel(String distNo, Integer level) {
        Map<String, Object> params = new HashMap<>();
        params.put("distNo", distNo + "%");
        params.put("level", level == 0 ? 6 : 9 );
        return EntityManagerUtil.queryForMapList(entityManager,
                "select distNo as distNo, distName as distName from " + getZcDBName() + "dist where distNo like :distNo and len(distNo)=:level order by distNo",
                params);
    }

    @Override
    public String getTopDistNo() {
        List<Map<String, Object>> distNos = EntityManagerUtil.queryForMapList(entityManager,
                "select top 1 distNo as distNo from " + getZcDBName() + "dist order by distNo",
                Collections.emptyMap());
        if (distNos.size() > 0) {
            return (String) distNos.get(0).get("distNo");
        }
        return "";
    }
}
